// <!-- 组件: zj-image 图片 选择&展示&上传 -->
// ==================== 参数 ====================
// ※ url ==> 双向绑定, 文件地址 (默认: [])
// ※ model ==> 双向绑定时父组件的键名
// ※ baseUrl ==> 前缀地址 (默认: $app.baseUrl)
// ※ maxlength ==> 最大允许上传个数, 不传则默认无限制 (默认: 0)
// ※ isEdit ==> 是否可编辑 (默认: true)
// ==================== 事件 ====================
// ※ bind:model="model(e)" ==> 双向绑定
// ※ bind:uploadEnd(e) ==> 上传结束后触发
//      e.detail = {
//        result: success/fail/complete, // 完成状态(全部成功/全部失败/有成功有失败)
//        successUp: 0, // 当前上传成功个数
//        failUp: 0 // 当前上传失败个数
//        other: null // 调用'upload'方法时传递进来的参数
//      }
// ==================== 方法 ====================
// ※ upload([model], [api], [other]) ==> 上传文件

const $app = getApp()
Component({
  properties: {
    url: { // 文件路径
      type: Array
    },
    model: { // 双向绑定时父组件的键名
      type: String
    },
    baseUrl: {
      type: String,
      value: $app.baseUrl
    },
    maxlength: { // 最大允许上传个数
      type: Number,
      value: 0
    },
    isEdit: { // 不可添加 展示文件
      type: Boolean,
      optionalTypes: [String, Number, Boolean],
      value: true
    }
  },
  data: {
    url_child: [], // 文件路径, 与'url'双向绑定使用(注: 不能直接改变'url', 否则监听赋值会变成死循环)
    files: [], // 图片路径
    uploadNum: 0, // 上传总数
    successUp: 0, // 当前上传成功个数
    failUp: 0, // 当前上传失败个数
    completeUp: 0, // 当前上传完成个数 监听
    other: null // 调用'upload'方法时传递进来的参数
  },
  observers: {
    // ========== 监听'url', 双向绑定 ==========
    'url': function (url) {
      const url_str = url.toString()
      const url_child_str = this.data.url_child.toString()
      if (url_str !== url_child_str) {
        let files = []
        url.forEach(b =>{ files.push(this.properties.baseUrl + b) })
        this.setData({
          url_child: url,
          files
        })
      }
    },
    'url_child': function (url_child) {
      const e = {
        value: this.data.url_child,
        model: this.properties.model
      }
      this.triggerEvent('model', e)
    },
    // ========== 监听'当前上传完成个数', 判断上传时间是否完成 ==========
    'completeUp': function (completeUp) {
      const uploadNum = this.data.uploadNum
      const successUp = this.data.successUp
      const failUp = this.data.failUp
      const text = `已上传${successUp}个`
      $app.$common.openLoading(text, 'loading')
      if (completeUp && completeUp === uploadNum) {
        const e = {
          result: null,
          failUp: failUp,
          successUp: successUp,
          other: this.data.other
        }
        if (successUp === uploadNum) {
          e.result = 'success'
        } else if (failUp === uploadNum) {
          e.result = 'fail'
        } else {
          e.result = 'complete'
        }
        this.triggerEvent('uploadEnd', e)
      }
    }
  },
  methods: {
    // ======== 添加 ========
    add () {
      const maxlength = this.properties.maxlength
      const fileslength = this.data.files.length
      if (maxlength && fileslength >= maxlength) return
      wx.chooseImage({
        count: 9,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success: (e) => {
          let newfiles = e.tempFilePaths || []
          if (maxlength && newfiles.length + fileslength > maxlength) {
            newfiles.length = maxlength - fileslength
          }
          let url_child = Array.from(this.data.url_child)
          let files = Array.from(this.data.files)
          newfiles.forEach(b => {
            url_child.push(0)
            files.push(b)
          })
          this.setData({ url_child, files })
        }
      })
    },
    // ======== 删除 ========
    del (e) {
      const index = e.currentTarget.dataset.index // 选中当前下标
      let url_child = Array.from(this.data.url_child) // 文件路径
      let files = Array.from(this.data.files) // 文件集
      url_child.splice(index, 1)
      files.splice(index, 1)
      this.setData({ url_child, files })
    },
    // ======== 展示图片 ========
    showImage (e) {
      let url = e.currentTarget.dataset.url
      wx.previewImage({
        current: url, // 当前显示图片的http链接
        urls: this.data.files // 需要预览的图片http链接列表
      })
    },
    // ======== 上传 ========
    // 注: 'other'仅做传递使用
    upload (model, api, other) {
      this.setData({
        other: other, // 传递参数
        uploadNum: 0, successUp: 0, failUp: 0, completeUp: 0 // 初始化上传相关数据
      })
      const url = this.properties.baseUrl + model + '/' + api // 地址
      let files = []
      this.data.url_child.forEach((b, i) => {
        b === 0 && files.push({ i: i, path: this.data.files[i] })
      })
      if (files.length) {
        this.setData({ uploadNum: files.length }) // 上传总数
        files.forEach(b => { this.uploadfile(url, b) }) // 调用上传文件方法
      } else {
        const e = {
          result: 'success',
          failUp: 0,
          successUp: 0,
          other: other
        }
        this.triggerEvent('uploadEnd', e)
      }
    },
    uploadfile (url, b) { // 上传文件方法
      wx.uploadFile({
        url: url,
        filePath: b.path,
        name: 'file',
        header: { 
          'Content-Type': 'multipart/form-data',
          'accept': 'application/json'
        },
        success: (e) => {
          let data = JSON.parse(e.data).data || ''
          this.setData({
            [`url_child[${b.i}]`]: data,
            [`files[${b.i}]`]: this.properties.baseUrl + data,
            successUp: this.data.successUp + 1 // 成功+1
          })
        },
        fail: (e) => {
          this.setData({ failUp: this.data.failUp + 1 }) // 失败+1
        },
        complete: (e) =>{
          this.setData({ completeUp: this.data.completeUp + 1 }) // 完成+1
        }
      })
    }
  }
})
